package cn.xianshu.service.impl;

import cn.xianshu.CourseConstans.CourseDto;
import cn.xianshu.constants.BaseConstants;
import cn.xianshu.context.LoginContextHandel;
import cn.xianshu.coursedto.CourseDoc;
import cn.xianshu.domain.Course;
import cn.xianshu.domain.CourseDetail;
import cn.xianshu.domain.CourseMarket;
import cn.xianshu.domain.Login;
import cn.xianshu.feign.client.CourseESFeignClient;
import cn.xianshu.mapper.CourseDetailMapper;
import cn.xianshu.mapper.CourseMapper;
import cn.xianshu.mapper.CourseMarketMapper;
import cn.xianshu.service.ICourseService;
import cn.xianshu.to.EmailTo;
import cn.xianshu.to.MessageTo;
import cn.xianshu.to.SMSTo;
import cn.xianshu.util.AjaxResult;
import cn.xianshu.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;

import static cn.xianshu.constants.RabbitMQConstans.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Uncle Xian
 * @since 2021-11-26
 */
@Service
@Transactional
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseDetailMapper courseDetailMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private CourseESFeignClient courseESFeignClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     *  保存上传课件
     *  1.获取数据对象
     *  2.将Course数据保存到数据库
     *  3.将CourseDetail数据保存
     *  4.将CourseMarket数据保存
     * @param dto
     */
    @Override
    public void save(CourseDto dto) {
        // 获取登录用户的信息
        Login login = LoginContextHandel.getLogin();
        AssertUtil.isNotNull(login, "请登录!");
        // 1.获取数据对象
        Course course = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseMarket courseMarket = dto.getCourseMarket();
        // 2.校验参数， 课程名是否重复
        Wrapper entityWrapper = new EntityWrapper();
        entityWrapper.eq("name", course.getName()); // 去重
        Course course2 = super.selectOne(entityWrapper);
        AssertUtil.isNull(course2, "课程名已存在!"); // 断言

        // 2.将Course数据保存到数据库
        course.setStatus(BaseConstants.course.COURSE_OFF_ONLINE); // 状态默认为0 未上线

        course.setOnlineTime(new Date()); // 课程上线时间
        // 这里使用的是login的id  不是 employee的id
        course.setUserId(login.getId());
        course.setUserName(login.getUsername());
        course.setTenantId(login.getTenantId());
        course.setTenantName(login.getTenantName());
        course.setCommentCount(0);
        course.setSaleCount(0);
        course.setViewCount(0);
        super.insert(course);
        // 3.将CourseDetail数据保存

        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);

        // 4.将CourseMarket数据保存
        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);


    }



    /**
     * 上线发布
     * 1.获取需要上线的数据
     * 2.判断数据是否为下线状态
     * 3.修改状态
     * 4.保存到ES中
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onLineCourse(Long id) {
        // 1.获取需要上线的数据
        Course course = super.selectById(id);
        // 2.判断数据是否为下线状态
        AssertUtil.isEqual(course.getStatus(), BaseConstants.course.COURSE_OFF_ONLINE, "请选择状态为下线的数据!");
        // 3.修改状态
        course.setStatus(BaseConstants.course.COURSE_ON_ONLINE);
        course.setOnlineTime(new Date());
        super.updateById(course);


        // 4.保存到ES中
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        CourseDoc courseDoc = new CourseDoc();

        // 将两个对象集合成一个
        BeanUtils.copyProperties(courseMarket, courseDoc);
        BeanUtils.copyProperties(course, courseDoc);
        // 收费
        courseDoc.setChargeName(courseMarket.getCharge() == 2 ? "收费" : "免费");
        AjaxResult result = courseESFeignClient.save(courseDoc);
        AssertUtil.isTrue(result.isSuccess(), "课程发布失败!");


        // 调用消息发布
        publishmessage(course);
    }


    //SPEL
    @Value("${message.content.sms.course-publish}")
    public String smsContent;

    @Value("${message.content.email.course-publish}")
    public String emailContent;

    @Value("${message.content.message.course-publish}")
    public String messageContent;


    /**
     * 消息发布
     */
    private void publishmessage(Course course){
        // 发送消息到MQ
        //发短信，用临时变量来接收配置信息，做拼接操作
        String tempSmsContent = String.format(smsContent,course.getName() );

        rabbitTemplate.convertAndSend(QUEUE_NAME_OF_TOPIC,//交换机名字
                "course.sms" ,//路由键
                new SMSTo(Arrays.asList("18233333333","18233333333") ,tempSmsContent));

        //发邮件
        String tempEmailContent = String.format(emailContent,course.getName() );

        rabbitTemplate.convertAndSend(QUEUE_NAME_OF_TOPIC,//交换机名字
                "course.email" ,//路由键
                new EmailTo(Arrays.asList("182333@qq.com","182332@qq.com"),"有课程发布啦" ,tempEmailContent));

        //发邮件
        String tempMessageContent = String.format(messageContent,course.getName() );

        rabbitTemplate.convertAndSend(QUEUE_NAME_OF_TOPIC,//交换机名字
                "course.message" ,//路由键
                new MessageTo(Arrays.asList(1L,2L),"有课程发布啦" ,tempMessageContent));
    }





    /**
     * 课件下线
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offLineCourse(Long id) {
        // 查询要下线的课件
        Course course = super.selectById(id);
        // 判断数据是不是上线状态
        AssertUtil.isEquals(course.getStatus(), BaseConstants.course.COURSE_ON_ONLINE, "请选择上线的课件!");
        // 修改状态  时间
        course.setStatus(BaseConstants.course.COURSE_OFF_ONLINE);
        course.setOfflineTime(new Date());
        super.updateById(course);

        // 删除该数据在ES中的数据
        AjaxResult remove = courseESFeignClient.remove(id);
        AssertUtil.isTrue(remove.isSuccess(), "商品下架失败!");
    }
}
